import json
import requests
from django.shortcuts import render,redirect
from web import models
from web.forms.file import FolderModelForm,FileModelForm
from django.http import JsonResponse,HttpResponse
from django.forms import model_to_dict
from django.urls import reverse
from utils.tecent.cos import delete_file,delete_file_list,credential
from django.views.decorators.csrf import csrf_exempt

def file(request,project_id):
    parent_object = None
    edit_object = None
    folder_id = request.GET.get('folder', '')  # 有值传id，没值为空，防止不是数字报错

    #判断路径是否合法
    if folder_id.isdecimal():
        parent_object = models.File.objects.filter(id=int(folder_id), file_type=2,project=request.tracer.project).first()

    if request.method == 'GET':
        #获取目录
        queryset = models.File.objects.filter(project=request.tracer.project)
        if parent_object:
            file_object_list = queryset.filter(parent=parent_object).order_by('-file_type')
        else:
            file_object_list = queryset.filter(parent__isnull=True).order_by('-file_type')
        #实现目录导航条，层级目录
        parent_list=[]
        parent = parent_object
        while parent:
            #parent_list.insert(0,{'id':parent.id,'name':parent.name})
            parent_list.insert(0,model_to_dict(parent,['id',"name"]))
            parent = parent.parent

        form = FolderModelForm(request,parent_object)
        context = {
            'form': form,
            'file_object_list': file_object_list,
            'parent_list': parent_list,
            'folder_object': parent_object,
        }
        return render(request,'file.html',context)
    #添加文件夹和修改文件夹
    fid = request.POST.get('fid','')
    if fid.isdecimal():
        #修改文件夹
        edit_object = models.File.objects.filter(id=int(fid), file_type=2, project=request.tracer.project).first()
    if edit_object:
        form = FolderModelForm(request, parent_object, data=request.POST,instance=edit_object)
    else:
        #添加文件夹
        form = FolderModelForm(request,parent_object,data=request.POST)
    if form.is_valid():
        form.instance.project = request.tracer.project
        form.instance.file_type =2
        form.instance.update_user = request.tracer.user
        form.instance.parent = parent_object
        form.save()
        return JsonResponse({'status':True, 'error': form.errors})

    return JsonResponse({'status':False,'error':form.errors})

def file_delete(request, project_id):
    """ 删除文件 """
    fid = request.GET.get('fid')

    # 删除数据库中的 文件 & 文件夹 （级联删除）
    delete_object = models.File.objects.filter(id=fid, project=request.tracer.project).first()
    if delete_object.file_type == 1:
        # 删除文件，将容量还给当前项目的已使用空间
        request.tracer.project.use_space -= delete_object.file_size
        request.tracer.project.save()

        # cos中删除文件
        delete_file(request.tracer.project.bucket, request.tracer.project.region, delete_object.key)

        # 在数据库中删除当前文件
        delete_object.delete()

        return JsonResponse({'status': True})

    # 删除文件夹（找到文件夹下所有的文件->数据库文件删除、cos文件删除、项目已使用空间容量还回去）
    # delete_object
    # 找他下面的 文件和文件夹
    # models.FileRepository.objects.filter(parent=delete_object) # 文件 删除；文件夹 继续向里差

    total_size = 0
    key_list = []

    folder_list = [delete_object, ]
    for folder in folder_list:
        child_list = models.File.objects.filter(project=request.tracer.project, parent=folder).order_by(
            '-file_type')
        for child in child_list:
            if child.file_type == 2:
                folder_list.append(child)
            else:
                # 文件大小汇总
                total_size += child.file_size

                # 删除文件
                key_list.append({"Key": child.key})

    # cos 批量删除文件
    if key_list:
        delete_file_list(request.tracer.project.bucket, request.tracer.project.region, key_list)

    # 归还容量
    if total_size:
        request.tracer.project.use_space -= total_size
        request.tracer.project.save()

    # 删除数据库中的文件
    delete_object.delete()
    return JsonResponse({'status': True})

'''后端实现删除文件/文件夹
def file_delete(request,project_id,file_id):
    #获取当前要删除的文件
    deleted_file = models.File.objects.filter(project_id=project_id, id=file_id).first()
    #获取他的父id
    parent_id = deleted_file.parent.id if deleted_file.parent else None
    #删除当前文件
    models.File.objects.filter(project_id=project_id, id=file_id).delete()
    if parent_id:
        url = reverse('file', kwargs={'project_id': project_id}) + '?folder=' + str(parent_id)
    else:
        url = reverse('file', kwargs={'project_id': project_id})
    return redirect(url)'''
@csrf_exempt
def cos_credential(request,project_id):
    file_list = json.loads(request.body.decode('utf-8'))#接受来自checkFileList的数据，得到的是列表不是对象
    total_size = 0
    project_space = request.tracer.price_policy.project_space*1024*1024
    per_file_size = request.tracer.price_policy.per_file_size*1024*1024
    project_use_space = request.tracer.project.use_space
    project_remaining_space = project_space - project_use_space

    for file in file_list:
        #文件大小B，单文件的限制单位M
        if file['size']>per_file_size:
            return JsonResponse({'status':False,'error':'[{}]文件超出单文件限制'.format(file['name'])})
        total_size += file['size']
    print("total_size:{}".format(total_size))
    print("project_space:{}".format(project_space))
    print("project_use_space:{}".format(project_use_space))
    print("project_remaining_space:{}".format(project_remaining_space))
    if total_size > project_remaining_space:
        return JsonResponse({'status': False, 'error': '传输文件超出文件能传输的最大的限制'})

    data_dict = credential(request.tracer.project.bucket, request.tracer.project.region)
    #return JsonResponse(data_dict)
    return JsonResponse({'status':True, 'data':data_dict})
@csrf_exempt
def file_post(request,project_id):
    #已上传成功的文件写入数据库
    '''<QueryDict:
    {
    'name': ['IMG_20200914_122143.jpg'],
    'file_size': ['675814'],
     'key': ['1740452477643_IMG_20200914_122143.jpg'],
     'parent': ['14'],
     'etag': ['"4aa03d6727b538a3d105ff6ec26dac0a"'],
     'file_path': ['chandao-17357866893-1740406113-1339193718.cos.ap-beijing.myqcloud.com/1740452477643_IMG_20200914_122143.jpg']
     }>'''
    form = FileModelForm(request,data = request.POST)
    if form.is_valid():
        '''form.instance.file_type = 1
        form.instance.update_user = request.tracer.user
        instance = form.save()无法获取file_type的中文'''
        data_dict = form.cleaned_data
        data_dict.pop('etag')
        data_dict.update({'file_type':1,'project':request.tracer.project,'update_user':request.tracer.user})
        instance = models.File.objects.create(**data_dict)
        print()
        #项目已使用空间增加
        request.tracer.project.use_space += data_dict['file_size']
        request.tracer.project.save()
        result = {
            'id': instance.id,
            'name': instance.name,
            'file_size': instance.file_size,
            'username': instance.update_user.username,
            'datetime': instance.update_time.strftime("%Y年%m月%d日 %H:%M"),
            'download_url':reverse('file_download', kwargs={'project_id': project_id,'file_id':instance.id })
        }

        return JsonResponse({'status':True,'data':result})
    return JsonResponse({'status':False,'data':'文件错误'})

def file_download(request,project_id,file_id):

    #打开文件，获取文件内容（要去cos，post不行）
    file_object = models.File.objects.filter(project_id=project_id, id=file_id).first()
    #添加响应头
    res = requests.get(file_object.file_path)

    # 文件分块处理（适用于大文件）
    data = res.iter_content()

    # 设置content_type=application/octet-stream 用于提示下载框
    response = HttpResponse(data, content_type="application/octet-stream")
    from django.utils.encoding import escape_uri_path

    # 设置响应头：中文件文件名转义
    response['Content-Disposition'] = "attachment; filename={};".format(escape_uri_path(file_object.name))
    return response

